สำรวจทางเลือก TypeScript ที่ทรงพลังแทน enums: การยืนยันค่าคงที่ (const assertions) และ Union Types เรียนรู้ว่าควรใช้แต่ละตัวเมื่อใดเพื่อโค้ดที่แข็งแกร่งและดูแลรักษาง่าย
เหนือกว่า Enums: การยืนยันค่าคงที่ (Const Assertions) ของ TypeScript เทียบกับ Union Types
ในโลกของ JavaScript ที่มีการกำหนดไทป์อย่างตายตัวด้วย TypeScript, enums เป็นที่นิยมมานานสำหรับการแสดงชุดค่าคงที่ที่มีชื่อกำหนดไว้ พวกมันนำเสนอวิธีการที่ชัดเจนและอ่านง่ายในการกำหนดชุดของค่าที่เกี่ยวข้อง อย่างไรก็ตาม เมื่อโปรเจกต์เติบโตและพัฒนา นักพัฒนามักจะมองหาทางเลือกที่ยืดหยุ่นกว่าและบางครั้งก็มีประสิทธิภาพมากกว่า สองทางเลือกที่ทรงพลังซึ่งมักจะปรากฏออกมาคือ const assertions (การยืนยันค่าคงที่) และ union types (ไทป์รวม) โพสต์นี้จะเจาะลึกความแตกต่างของการใช้ทางเลือกเหล่านี้แทน enums แบบดั้งเดิม พร้อมให้ตัวอย่างที่เป็นประโยชน์และแนะนำว่าควรเลือกใช้อันไหนเมื่อใด
ทำความเข้าใจ TypeScript Enums แบบดั้งเดิม
ก่อนที่เราจะสำรวจทางเลือกอื่น ๆ สิ่งสำคัญคือต้องเข้าใจอย่างถ่องแท้ว่า TypeScript enums มาตรฐานทำงานอย่างไร Enums ช่วยให้คุณสามารถกำหนดชุดของค่าคงที่ตัวเลขหรือสตริงที่มีชื่อได้ พวกมันสามารถเป็นตัวเลข (ค่าเริ่มต้น) หรือเป็นสตริงได้
Enums แบบตัวเลข
โดยค่าเริ่มต้น สมาชิก enum จะถูกกำหนดค่าตัวเลขโดยเริ่มจาก 0
enum DirectionNumeric {
Up,
Down,
Left,
Right
}
let myDirection: DirectionNumeric = DirectionNumeric.Up;
console.log(myDirection); // Output: 0
คุณยังสามารถกำหนดค่าตัวเลขได้อย่างชัดเจน
enum StatusCode {
Success = 200,
NotFound = 404,
InternalError = 500
}
let responseStatus: StatusCode = StatusCode.Success;
console.log(responseStatus); // Output: 200
Enums แบบสตริง
Enums แบบสตริงมักเป็นที่นิยมมากกว่า เนื่องจากช่วยให้การดีบั๊กดีขึ้น เพราะชื่อสมาชิกจะถูกเก็บไว้ใน JavaScript ที่คอมไพล์แล้ว
enum ColorString {
Red = "RED",
Green = "GREEN",
Blue = "BLUE"
}
let favoriteColor: ColorString = ColorString.Blue;
console.log(favoriteColor); // Output: "BLUE"
ภาระ (Overhead) ของ Enums
แม้ว่า enums จะสะดวก แต่ก็มาพร้อมกับภาระเล็กน้อย เมื่อคอมไพล์เป็น JavaScript, TypeScript enums จะถูกเปลี่ยนเป็นอ็อบเจกต์ที่มักจะมี reverse mappings (เช่น การแมปค่าตัวเลขกลับไปยังชื่อ enum) สิ่งนี้มีประโยชน์ แต่ก็เพิ่มขนาดของ bundle และอาจไม่จำเป็นเสมอไป
พิจารณา enum แบบสตริงง่ายๆ นี้:
enum Status {
Pending = "PENDING",
Processing = "PROCESSING",
Completed = "COMPLETED"
}
ใน JavaScript สิ่งนี้อาจกลายเป็นบางอย่างเช่น:
var Status;
(function (Status) {
Status["Pending"] = "PENDING";
Status["Processing"] = "PROCESSING";
Status["Completed"] = "COMPLETED";
})(Status || (Status = {}));
สำหรับชุดค่าคงที่ที่อ่านอย่างเดียวและเรียบง่าย โค้ดที่สร้างขึ้นนี้อาจรู้สึกมากเกินไป
ทางเลือกที่ 1: Const Assertions (การยืนยันค่าคงที่)
Const assertions เป็นฟีเจอร์ TypeScript ที่ทรงพลังซึ่งช่วยให้คุณบอกคอมไพเลอร์ให้คาดเดาไทป์ที่เฉพาะเจาะจงที่สุดสำหรับค่าได้ เมื่อใช้กับอาร์เรย์หรืออ็อบเจกต์ที่มีวัตถุประสงค์เพื่อแสดงชุดค่าคงที่ พวกมันสามารถเป็นทางเลือกที่เบาและมีประสิทธิภาพแทน enums ได้
Const Assertions กับ Arrays
คุณสามารถสร้างอาร์เรย์ของสตริงลิเทอรัล แล้วใช้การยืนยัน const เพื่อทำให้ไทป์ของมันไม่สามารถเปลี่ยนแปลงได้ และทำให้สมาชิกของมันเป็น literal types
const statusArray = ["PENDING", "PROCESSING", "COMPLETED"] as const;
type StatusType = typeof statusArray[number];
let currentStatus: StatusType = "PROCESSING";
// currentStatus = "FAILED"; // Error: Type '"FAILED"' is not assignable to type 'StatusType'.
function processStatus(status: StatusType) {
console.log(`Processing status: ${status}`);
}
processStatus("COMPLETED");
มาทำความเข้าใจสิ่งที่เกิดขึ้นที่นี่:
as const: การยืนยันนี้บอก TypeScript ให้ถือว่าอาร์เรย์เป็นแบบอ่านอย่างเดียว และอนุมาน literal types ที่เฉพาะเจาะจงที่สุดสำหรับสมาชิกของมัน ดังนั้น แทนที่จะเป็นstring[], ไทป์จะกลายเป็นreadonly ["PENDING", "PROCESSING", "COMPLETED"].typeof statusArray[number]: นี่คือ mapped type มันจะวนซ้ำทุกดัชนีของstatusArrayและดึง literal types ออกมา index signaturenumberโดยพื้นฐานแล้วหมายถึง "ให้ไทป์ของสมาชิกใดๆ ในอาร์เรย์นี้" ผลลัพธ์คือ union type:"PENDING" | "PROCESSING" | "COMPLETED".
วิธีการนี้ให้ความปลอดภัยของไทป์คล้ายกับ string enums แต่สร้าง JavaScript น้อยที่สุด statusArray เองยังคงเป็นอาร์เรย์ของสตริงใน JavaScript
Const Assertions กับ Objects
Const assertions มีประสิทธิภาพมากยิ่งขึ้นเมื่อนำไปใช้กับอ็อบเจกต์ คุณสามารถกำหนดอ็อบเจกต์ที่คีย์แทนค่าคงที่ที่คุณตั้งชื่อ และค่าเป็นสตริงลิเทอรัลหรือตัวเลข
const userRoles = {
Admin: "ADMIN",
Editor: "EDITOR",
Viewer: "VIEWER"
} as const;
type UserRole = typeof userRoles[keyof typeof userRoles];
let currentUserRole: UserRole = "EDITOR";
// currentUserRole = "GUEST"; // Error: Type '"GUEST"' is not assignable to type 'UserRole'.
function displayRole(role: UserRole) {
console.log(`User role is: ${role}`);
}
displayRole(userRoles.Admin); // Valid
displayRole("EDITOR"); // Valid
ในตัวอย่างอ็อบเจกต์นี้:
as const: การยืนยันนี้ทำให้อ็อบเจกต์ทั้งหมดเป็นแบบอ่านอย่างเดียว ที่สำคัญกว่านั้น มันจะอนุมาน literal types สำหรับค่าคุณสมบัติทั้งหมด (เช่น"ADMIN"แทนstring) และทำให้คุณสมบัติเหล่านั้นเป็นแบบอ่านอย่างเดียวkeyof typeof userRoles: นิพจน์นี้ส่งผลให้เกิด union ของคีย์ของอ็อบเจกต์userRolesซึ่งคือ"Admin" | "Editor" | "Viewer".typeof userRoles[keyof typeof userRoles]: นี่คือ lookup type มันจะนำ union ของคีย์และใช้มันเพื่อค้นหาค่าที่สอดคล้องกันในไทป์userRolesสิ่งนี้ส่งผลให้เกิด union ของค่า:"ADMIN" | "EDITOR" | "VIEWER"ซึ่งเป็นไทป์ที่เราต้องการสำหรับบทบาท
เอาต์พุต JavaScript สำหรับ userRoles จะเป็นอ็อบเจกต์ JavaScript ธรรมดา:
var userRoles = {
Admin: "ADMIN",
Editor: "EDITOR",
Viewer: "VIEWER"
};
สิ่งนี้เบากว่า enum ทั่วไปอย่างมาก
เมื่อใดควรใช้ Const Assertions
- ค่าคงที่แบบอ่านอย่างเดียว: เมื่อคุณต้องการชุดของสตริงหรือตัวเลขลิเทอรัลที่คงที่ซึ่งไม่ควรเปลี่ยนแปลงขณะรันไทม์
- เอาต์พุต JavaScript น้อยที่สุด: หากคุณกังวลเกี่ยวกับขนาดของ bundle และต้องการการแสดงค่าคงที่ที่มีประสิทธิภาพสูงสุดในขณะรันไทม์
- โครงสร้างคล้ายอ็อบเจกต์: เมื่อคุณต้องการความสามารถในการอ่านของคู่คีย์-ค่า คล้ายกับวิธีที่คุณอาจจัดโครงสร้างข้อมูลหรือการกำหนดค่า
- ชุดที่ใช้สตริงเป็นหลัก: มีประโยชน์อย่างยิ่งสำหรับการแสดงสถานะ, ประเภท หรือหมวดหมู่ที่ระบุได้ดีที่สุดด้วยสตริงที่สื่อความหมาย
ทางเลือกที่ 2: Union Types (ไทป์รวม)
Union types ช่วยให้คุณสามารถประกาศว่าตัวแปรสามารถเก็บค่าของไทป์ใดไทป์หนึ่งจากหลายไทป์ได้ เมื่อรวมกับ literal types (สตริง, ตัวเลข, boolean literals) พวกมันจะสร้างวิธีการที่มีประสิทธิภาพในการกำหนดชุดของค่าที่อนุญาตโดยไม่จำเป็นต้องมีการประกาศค่าคงที่อย่างชัดเจนสำหรับชุดนั้น
Union Types กับ String Literals
คุณสามารถกำหนด union ของ string literals ได้โดยตรง
type TrafficLightColor = "RED" | "YELLOW" | "GREEN";
let currentLight: TrafficLightColor = "YELLOW";
// currentLight = "BLUE"; // Error: Type '"BLUE"' is not assignable to type 'TrafficLightColor'.
function changeLight(color: TrafficLightColor) {
console.log(`Changing light to: ${color}`);
}
changeLight("RED");
// changeLight("REDDY"); // Error
นี่เป็นวิธีที่ตรงไปตรงมาที่สุดและมักจะกระชับที่สุดในการกำหนดชุดของค่าสตริงที่อนุญาต
Union Types กับ Numeric Literals
ในทำนองเดียวกัน คุณสามารถใช้ numeric literals ได้
type HttpStatusCode = 200 | 400 | 404 | 500;
let responseCode: HttpStatusCode = 404;
// responseCode = 201; // Error: Type '201' is not assignable to type 'HttpStatusCode'.
function handleResponse(code: HttpStatusCode) {
if (code === 200) {
console.log("Success!");
} else {
console.log(`Error code: ${code}`);
}
}
handleResponse(500);
เมื่อใดควรใช้ Union Types
- ชุดที่เรียบง่ายและตรงไปตรงมา: เมื่อชุดของค่าที่อนุญาตมีขนาดเล็ก ชัดเจน และไม่ต้องการคีย์ที่สื่อความหมายนอกเหนือจากตัวค่าเอง
- ค่าคงที่โดยปริยาย: เมื่อคุณไม่จำเป็นต้องอ้างถึงค่าคงที่ที่มีชื่อสำหรับชุดนั้น แต่ใช้ค่าลิเทอรัลโดยตรง
- ความกระชับสูงสุด: สำหรับสถานการณ์ที่ไม่ซับซ้อนที่การกำหนดอ็อบเจกต์หรืออาร์เรย์เฉพาะดูเหมือนจะมากเกินไป
- พารามิเตอร์/ไทป์ส่งกลับของฟังก์ชัน: ยอดเยี่ยมสำหรับการกำหนดชุดที่แน่นอนของสตริงหรือตัวเลขที่ยอมรับได้สำหรับอินพุต/เอาต์พุตของฟังก์ชัน
เปรียบเทียบ Enums, Const Assertions และ Union Types
สรุปความแตกต่างที่สำคัญและกรณีการใช้งาน:
พฤติกรรมขณะรันไทม์
- Enums: สร้างอ็อบเจกต์ JavaScript ซึ่งอาจมี reverse mappings.
- Const Assertions (Arrays/Objects): สร้างอาร์เรย์หรืออ็อบเจกต์ JavaScript ธรรมดา ข้อมูลไทป์จะถูกลบออกขณะรันไทม์ แต่โครงสร้างข้อมูลยังคงอยู่
- Union Types (กับ literals): ไม่มีการแสดงผลขณะรันไทม์สำหรับ union เอง ค่าต่างๆ เป็นเพียง literals การตรวจสอบไทป์เกิดขึ้นที่เวลาคอมไพล์เท่านั้น
ความสามารถในการอ่านและการแสดงออก
- Enums: มีความสามารถในการอ่านสูง โดยเฉพาะอย่างยิ่งกับชื่อที่สื่อความหมาย อาจจะละเอียดกว่า
- Const Assertions (Objects): มีความสามารถในการอ่านที่ดีผ่านคู่คีย์-ค่า เลียนแบบการกำหนดค่าหรือการตั้งค่า
- Const Assertions (Arrays): อ่านได้น้อยกว่าสำหรับการแสดงค่าคงที่ที่มีชื่อ แต่เหมาะสำหรับรายการค่าที่จัดเรียงไว้
- Union Types: กระชับมาก ความสามารถในการอ่านขึ้นอยู่กับความชัดเจนของค่าลิเทอรัลนั้นๆ
ความปลอดภัยของไทป์
- ทั้งสามแนวทางให้ความปลอดภัยของไทป์ที่แข็งแกร่ง พวกมันรับประกันว่ามีเพียงค่าที่ถูกต้องและถูกกำหนดไว้ล่วงหน้าเท่านั้นที่สามารถกำหนดให้กับตัวแปรหรือส่งผ่านไปยังฟังก์ชันได้
ขนาด Bundle
- Enums: โดยทั่วไปมีขนาดใหญ่ที่สุดเนื่องจากมีการสร้างอ็อบเจกต์ JavaScript
- Const Assertions: เล็กกว่า enums เนื่องจากพวกมันสร้างโครงสร้างข้อมูลธรรมดา
- Union Types: เล็กที่สุด เนื่องจากพวกมันไม่ได้สร้างโครงสร้างข้อมูลรันไทม์ที่เฉพาะเจาะจงสำหรับไทป์นั้นเอง แต่เพียงอาศัยค่าลิเทอรัลเท่านั้น
ตารางกรณีการใช้งาน
นี่คือคู่มือฉบับย่อ:
| คุณสมบัติ | TypeScript Enum | Const Assertion (อ็อบเจกต์) | Const Assertion (อาร์เรย์) | Union Type (ลิเทอรัล) |
|---|---|---|---|---|
| เอาต์พุตรันไทม์ | JS Object (พร้อม reverse mapping) | Plain JS Object | Plain JS Array | ไม่มี (เฉพาะ literal values) |
| ความสามารถในการอ่าน (ค่าคงที่แบบมีชื่อ) | สูง | สูง | ปานกลาง | ต่ำ (ค่าคือชื่อ) |
| ขนาด Bundle | ใหญ่ที่สุด | ปานกลาง | ปานกลาง | เล็กที่สุด |
| ความยืดหยุ่น | ดี | ดี | ดี | ยอดเยี่ยม (สำหรับชุดที่เรียบง่าย) |
| การใช้งานทั่วไป | สถานะ, รหัสสถานะ, หมวดหมู่ | การกำหนดค่า, การกำหนดบทบาท, Feature Flags | รายการค่าที่ไม่เปลี่ยนรูปที่จัดเรียง | พารามิเตอร์ฟังก์ชัน, ค่าที่จำกัดแบบเรียบง่าย |
ตัวอย่างจริงและแนวปฏิบัติที่ดีที่สุด
ตัวอย่างที่ 1: การแสดงรหัสสถานะ API
Enum:
enum ApiStatus {
Success = "SUCCESS",
Error = "ERROR",
Pending = "PENDING"
}
function handleApiResponse(status: ApiStatus) {
// ... logic ...
}
Const Assertion (อ็อบเจกต์):
const apiStatusCodes = {
SUCCESS: "SUCCESS",
ERROR: "ERROR",
PENDING: "PENDING"
} as const;
type ApiStatus = typeof apiStatusCodes[keyof typeof apiStatusCodes];
function handleApiResponse(status: ApiStatus) {
// ... logic ...
}
Union Type:
type ApiStatus = "SUCCESS" | "ERROR" | "PENDING";
function handleApiResponse(status: ApiStatus) {
// ... logic ...
}
คำแนะนำ: สำหรับสถานการณ์นี้ union type มักจะเป็นวิธีที่กระชับและมีประสิทธิภาพที่สุด ค่าลิเทอรัลนั้นๆ ก็สื่อความหมายได้เพียงพอแล้ว หากคุณต้องการเชื่อมโยงเมตาดาตาเพิ่มเติมกับแต่ละสถานะ (เช่น ข้อความที่เป็นมิตรต่อผู้ใช้) อ็อบเจกต์ const assertion จะเป็นทางเลือกที่ดีกว่า
ตัวอย่างที่ 2: การกำหนดบทบาทผู้ใช้
Enum:
enum UserRoleEnum {
Admin = "ADMIN",
Moderator = "MODERATOR",
User = "USER"
}
function getUserPermissions(role: UserRoleEnum) {
// ... logic ...
}
Const Assertion (อ็อบเจกต์):
const userRolesObject = {
Admin: "ADMIN",
Moderator: "MODERATOR",
User: "USER"
} as const;
type UserRole = typeof userRolesObject[keyof typeof userRolesObject];
function getUserPermissions(role: UserRole) {
// ... logic ...
}
Union Type:
type UserRole = "ADMIN" | "MODERATOR" | "USER";
function getUserPermissions(role: UserRole) {
// ... logic ...
}
คำแนะนำ: อ็อบเจกต์ const assertion สร้างสมดุลที่ดีในที่นี้ มันให้คู่คีย์-ค่าที่ชัดเจน (เช่น userRolesObject.Admin) ซึ่งช่วยเพิ่มความสามารถในการอ่านเมื่ออ้างอิงถึงบทบาท ในขณะที่ยังคงมีประสิทธิภาพ Union type ก็เป็นตัวเลือกที่แข็งแกร่งมากหาก string literals โดยตรงเพียงพอ
ตัวอย่างที่ 3: การแสดงตัวเลือกการกำหนดค่า
ลองจินตนาการถึงอ็อบเจกต์การกำหนดค่าสำหรับแอปพลิเคชันทั่วโลกที่อาจมีธีมที่แตกต่างกัน
Enum:
enum Theme {
Light = "light",
Dark = "dark",
System = "system"
}
interface AppConfig {
theme: Theme;
// ... other config options ...
}
Const Assertion (อ็อบเจกต์):
const themes = {
Light: "light",
Dark: "dark",
System: "system"
} as const;
type Theme = typeof themes[keyof typeof themes];
interface AppConfig {
theme: Theme;
// ... other config options ...
}
Union Type:
type Theme = "light" | "dark" | "system";
interface AppConfig {
theme: Theme;
// ... other config options ...
}
คำแนะนำ: สำหรับการตั้งค่าการกำหนดค่า เช่น ธีม, อ็อบเจกต์ const assertion มักจะเหมาะที่สุด มันกำหนดตัวเลือกที่มีอยู่และค่าสตริงที่สอดคล้องกันอย่างชัดเจน คีย์ (Light, Dark, System) เป็นแบบที่สื่อความหมายและแมปโดยตรงกับค่า ทำให้โค้ดการกำหนดค่าเข้าใจได้ง่ายมาก
การเลือกเครื่องมือที่เหมาะสมกับงาน
การตัดสินใจเลือกระหว่าง TypeScript enums, const assertions และ union types ไม่ได้เป็นเรื่องขาวดำเสมอไป มักจะขึ้นอยู่กับการแลกเปลี่ยนระหว่างประสิทธิภาพขณะรันไทม์, ขนาด bundle และความสามารถในการอ่าน/การแสดงออกของโค้ด
- เลือกใช้ Union Types เมื่อคุณต้องการชุดของ string หรือ number literals ที่เรียบง่ายและจำกัด และต้องการความกระชับสูงสุด พวกมันยอดเยี่ยมสำหรับ function signatures และข้อจำกัดค่าพื้นฐาน
- เลือกใช้ Const Assertions (กับ Objects) เมื่อคุณต้องการวิธีการที่จัดโครงสร้างและอ่านง่ายขึ้นในการกำหนดค่าคงที่ที่มีชื่อ คล้ายกับ enum แต่มีภาระรันไทม์ที่น้อยกว่ามาก สิ่งนี้เหมาะสำหรับการกำหนดค่า, บทบาท หรือชุดใดๆ ที่คีย์เพิ่มความหมายสำคัญ
- เลือกใช้ Const Assertions (กับ Arrays) เมื่อคุณเพียงแค่ต้องการรายการค่าที่ไม่เปลี่ยนรูปที่จัดเรียงไว้ และการเข้าถึงโดยตรงผ่านดัชนีมีความสำคัญมากกว่าคีย์ที่มีชื่อ
- พิจารณา TypeScript Enums เมื่อคุณต้องการคุณสมบัติเฉพาะของมัน เช่น reverse mapping (แม้ว่าสิ่งนี้จะพบน้อยลงในการพัฒนาสมัยใหม่) หรือหากทีมของคุณมีความชอบที่แข็งแกร่งและผลกระทบต่อประสิทธิภาพไม่มีนัยสำคัญสำหรับโปรเจกต์ของคุณ
ในโปรเจกต์ TypeScript สมัยใหม่หลายแห่ง คุณจะพบว่ามีการเอียงไปทาง const assertions และ union types มากกว่า enums แบบดั้งเดิม โดยเฉพาะอย่างยิ่งสำหรับค่าคงที่ที่ใช้สตริง เนื่องจากคุณลักษณะด้านประสิทธิภาพที่ดีกว่าและเอาต์พุต JavaScript ที่มักจะเรียบง่ายกว่า
ข้อพิจารณาทั่วโลก
เมื่อพัฒนาแอปพลิเคชันสำหรับผู้ชมทั่วโลก การกำหนดค่าคงที่ที่สอดคล้องและคาดการณ์ได้เป็นสิ่งสำคัญ ทางเลือกที่เราได้กล่าวถึง (enums, const assertions, union types) ล้วนมีส่วนช่วยในการสร้างความสอดคล้องนี้โดยการบังคับใช้ความปลอดภัยของไทป์ในสภาพแวดล้อมและภาษาของผู้พัฒนาที่แตกต่างกัน
- ความสอดคล้อง: ไม่ว่าวิธีใดที่เลือกใช้ สิ่งสำคัญคือความสอดคล้องภายในโปรเจกต์ของคุณ หากคุณตัดสินใจใช้อ็อบเจกต์ const assertion สำหรับบทบาท ให้ยึดตามรูปแบบนั้นตลอดทั้งโค้ดเบส
- การรองรับหลายภาษา (i18n): เมื่อกำหนดป้ายกำกับหรือข้อความที่จะถูกแปลเป็นภาษาต่างๆ ให้ใช้โครงสร้างที่ปลอดภัยทางไทป์เหล่านี้เพื่อให้แน่ใจว่ามีการใช้เฉพาะคีย์หรือตัวระบุที่ถูกต้องเท่านั้น สตริงที่แปลจริงจะถูกจัดการแยกต่างหากผ่านไลบรารี i18n ตัวอย่างเช่น หากคุณมีฟิลด์
statusที่สามารถเป็น "PENDING", "PROCESSING", "COMPLETED" ไลบรารี i18n ของคุณจะแมปตัวระบุภายในเหล่านี้ไปยังข้อความแสดงผลที่แปลเป็นภาษาท้องถิ่น - เขตเวลาและสกุลเงิน: แม้ว่าจะไม่เกี่ยวข้องโดยตรงกับ enums แต่โปรดจำไว้ว่าเมื่อต้องจัดการกับค่าต่างๆ เช่น วันที่ เวลา หรือสกุลเงิน ระบบไทป์ของ TypeScript สามารถช่วยบังคับใช้การใช้งานที่ถูกต้องได้ แต่โดยทั่วไปแล้วจำเป็นต้องมีไลบรารีภายนอกสำหรับการจัดการทั่วโลกที่แม่นยำ ตัวอย่างเช่น ไทป์ union
Currencyอาจถูกกำหนดเป็น "USD" | "EUR" | "GBP" แต่ตรรกะการแปลงจริงต้องใช้เครื่องมือเฉพาะทาง
บทสรุป
TypeScript มีชุดเครื่องมือที่หลากหลายสำหรับการจัดการค่าคงที่ แม้ว่า enums จะมีประโยชน์กับเรามาโดยตลอด แต่ const assertions และ union types ก็เป็นทางเลือกที่น่าสนใจและมักจะมีประสิทธิภาพสูงกว่า ด้วยการทำความเข้าใจความแตกต่างของพวกมันและการเลือกแนวทางที่เหมาะสมตามความต้องการเฉพาะของคุณ—ไม่ว่าจะเป็นประสิทธิภาพ, ความสามารถในการอ่าน หรือความกระชับ—คุณสามารถเขียนโค้ด TypeScript ที่แข็งแกร่ง, ดูแลรักษาง่าย และมีประสิทธิภาพมากขึ้นซึ่งสามารถปรับขนาดได้ทั่วโลก
การยอมรับทางเลือกเหล่านี้สามารถนำไปสู่ขนาด bundle ที่เล็กลง, แอปพลิเคชันที่เร็วขึ้น และประสบการณ์นักพัฒนาที่คาดการณ์ได้มากขึ้นสำหรับทีมต่างประเทศของคุณ